package com.aptemo.webetek.server;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import com.aptemo.webetek.client.commands.Action;
import com.aptemo.webetek.client.commands.Response;
import com.aptemo.webetek.client.exceptions.BackendException;
import com.aptemo.webetek.client.exceptions.WebetekLoginException;
import com.aptemo.webetek.server.datastore.DataStoreAPI;
import com.aptemo.webetek.server.datastore.DataStoreCache;
import com.aptemo.webetek.server.datastore.DataStoreImpl;
import com.aptemo.webetek.server.handlers.ActionHandler;
import com.aptemo.webetek.server.handlers.AssignResultHandler;
import com.aptemo.webetek.server.handlers.BetDetailsHandler;
import com.aptemo.webetek.server.handlers.BetsHandler;
import com.aptemo.webetek.server.handlers.BetsPagingHandler;
import com.aptemo.webetek.server.handlers.CreateEventHandler;
import com.aptemo.webetek.server.handlers.CreateLabelHandler;
import com.aptemo.webetek.server.handlers.CreatePaymentHandler;
import com.aptemo.webetek.server.handlers.CreateTeamHandler;
import com.aptemo.webetek.server.handlers.CurrentUserDetailsHandler;
import com.aptemo.webetek.server.handlers.DeleteEventHandler;
import com.aptemo.webetek.server.handlers.DeleteLabelHandler;
import com.aptemo.webetek.server.handlers.DeletePlayerHandler;
import com.aptemo.webetek.server.handlers.DeleteTeamHandler;
import com.aptemo.webetek.server.handlers.EventsHandler;
import com.aptemo.webetek.server.handlers.EventsPagingHandler;
import com.aptemo.webetek.server.handlers.GameDetailsHandler;
import com.aptemo.webetek.server.handlers.GetStatisticsHandler;
import com.aptemo.webetek.server.handlers.InvitationHandler;
import com.aptemo.webetek.server.handlers.JoinGroupHandler;
import com.aptemo.webetek.server.handlers.LabelsHandler;
import com.aptemo.webetek.server.handlers.LoginInfoHandler;
import com.aptemo.webetek.server.handlers.ModifyEventHandler;
import com.aptemo.webetek.server.handlers.ModifyPlayerHandler;
import com.aptemo.webetek.server.handlers.ModifyTeamHandler;
import com.aptemo.webetek.server.handlers.ModifyTeamStatusHandler;
import com.aptemo.webetek.server.handlers.PaymentsHandler;
import com.aptemo.webetek.server.handlers.PaymentsPagingHandler;
import com.aptemo.webetek.server.handlers.PickDetailsHandler;
import com.aptemo.webetek.server.handlers.PicksForEventHandler;
import com.aptemo.webetek.server.handlers.PlaceBetHandler;
import com.aptemo.webetek.server.handlers.PlayerDetailsHandler;
import com.aptemo.webetek.server.handlers.PlayersHandler;
import com.aptemo.webetek.server.handlers.PlayersPagingHandler;
import com.aptemo.webetek.server.handlers.TeamDetailsHandler;
import com.aptemo.webetek.server.handlers.TeamsHandler;
import com.aptemo.webetek.server.handlers.UserDetailsHandler;

/**
 * The server side implementation of the RPC service.
 */
public class ActionInvoker
{
	private Map<Class<? extends Action<?>>, ActionHandler>	commands;

	private static final Logger								log	= Logger.getLogger(ActionInvoker.class.getName());

	private DataStoreAPI									dbAPI;

	private HttpServletRequest								remoteService;

	public ActionInvoker()
	{
		dbAPI = new DataStoreCache(new DataStoreImpl());

		LabelsHandler a = new LabelsHandler(dbAPI);
		LoginInfoHandler l = new LoginInfoHandler(dbAPI);
		EventsHandler bh = new EventsHandler(dbAPI);
		CreateEventHandler abh = new CreateEventHandler(dbAPI);
		DeleteEventHandler dbh = new DeleteEventHandler(dbAPI);
		PlayersHandler ph = new PlayersHandler(dbAPI);
		DeleteLabelHandler dsh = new DeleteLabelHandler(dbAPI);
		ModifyEventHandler mbh = new ModifyEventHandler(dbAPI);
		BetsHandler sh = new BetsHandler(dbAPI);
		PlaceBetHandler ash = new PlaceBetHandler(dbAPI);
		UserDetailsHandler uia = new UserDetailsHandler(dbAPI);
		AssignResultHandler brh = new AssignResultHandler(dbAPI);
		TeamsHandler gugh = new TeamsHandler(dbAPI);
		CreateTeamHandler augh = new CreateTeamHandler(dbAPI);
		ModifyTeamHandler mugh = new ModifyTeamHandler(dbAPI);
		DeleteTeamHandler dlh = new DeleteTeamHandler(dbAPI);
		JoinGroupHandler jgh = new JoinGroupHandler(dbAPI);
		TeamDetailsHandler ugdh = new TeamDetailsHandler(dbAPI);
		GameDetailsHandler bdh = new GameDetailsHandler(dbAPI);
		ModifyPlayerHandler mph = new ModifyPlayerHandler(dbAPI);
		DeletePlayerHandler rph = new DeletePlayerHandler(dbAPI);
		CreateLabelHandler alh = new CreateLabelHandler(dbAPI);
		PlayerDetailsHandler pldh = new PlayerDetailsHandler(dbAPI);
		CreatePaymentHandler apmh = new CreatePaymentHandler(dbAPI);
		PaymentsHandler payh = new PaymentsHandler(dbAPI);
		InvitationHandler ih = new InvitationHandler(dbAPI);
		BetDetailsHandler sdh = new BetDetailsHandler(dbAPI);
		// AcceptEarningsHandler aeh = new AcceptEarningsHandler(this);
		EventsPagingHandler gph = new EventsPagingHandler(dbAPI);
		BetsPagingHandler bph = new BetsPagingHandler(dbAPI);
		PlayersPagingHandler pph = new PlayersPagingHandler(dbAPI);
		CurrentUserDetailsHandler cudh = new CurrentUserDetailsHandler(dbAPI);
		PaymentsPagingHandler payph = new PaymentsPagingHandler(dbAPI);
		// UserHandler ph =
		PickDetailsHandler pdh = new PickDetailsHandler(dbAPI);
		GetStatisticsHandler gsah = new GetStatisticsHandler(dbAPI);
		// DeleteStakeHandler delsh = new DeleteStakeHandler(dbAPI);

		PicksForEventHandler p4eh = new PicksForEventHandler(dbAPI);
		ModifyTeamStatusHandler mtsh = new ModifyTeamStatusHandler(dbAPI);

		commands = new HashMap<Class<? extends Action<?>>, ActionHandler>();
		commands.put(a.getActionType(), a);
		commands.put(l.getActionType(), l);
		commands.put(bh.getActionType(), bh);
		commands.put(abh.getActionType(), abh);
		commands.put(dbh.getActionType(), dbh);
		commands.put(ph.getActionType(), ph);
		commands.put(dsh.getActionType(), dsh);
		commands.put(mbh.getActionType(), mbh);
		commands.put(sh.getActionType(), sh);
		commands.put(ash.getActionType(), ash);
		// commands.put(delsh.getActionType(), delsh);
		commands.put(uia.getActionType(), uia);
		commands.put(brh.getActionType(), brh);
		commands.put(gugh.getActionType(), gugh);
		commands.put(augh.getActionType(), augh);
		commands.put(mugh.getActionType(), mugh);
		commands.put(dlh.getActionType(), dlh);
		commands.put(jgh.getActionType(), jgh);
		commands.put(ugdh.getActionType(), ugdh);
		commands.put(bdh.getActionType(), bdh);
		commands.put(pdh.getActionType(), pdh);
		commands.put(mph.getActionType(), mph);
		commands.put(rph.getActionType(), rph);
		commands.put(alh.getActionType(), alh);
		commands.put(pldh.getActionType(), pldh);
		commands.put(gsah.getActionType(), gsah);
		commands.put(apmh.getActionType(), apmh);
		commands.put(payh.getActionType(), payh);
		commands.put(ih.getActionType(), ih);
		commands.put(sdh.getActionType(), sdh);
		// commands.put(aeh.getActionType(), aeh);
		commands.put(gph.getActionType(), gph);
		commands.put(bph.getActionType(), bph);
		commands.put(pph.getActionType(), pph);
		commands.put(cudh.getActionType(), cudh);
		commands.put(p4eh.getActionType(), p4eh);
		commands.put(payph.getActionType(), payph);

		commands.put(mtsh.getActionType(), mtsh);
	}

	public <T extends Response> T invoke(Action<T> action, HttpServletRequest service) throws BackendException, WebetekLoginException
	{

		// try
		// {
		ActionHandler handler = commands.get(action.getClass());
		handler.setHttpServletRequest(service);
		return (T) handler.invoke(action);
		// }
		// catch (NullPointerException e)
		// {
		//
		// if (action != null)
		// {
		// log.severe("Null pointer exception when executing: " +
		// action.getClass().getName());
		// throw new BackendException(EErrorCodes.SERVER_ERROR);
		// }
		// throw new BackendException(EErrorCodes.SERVER_ERROR);
		// }
		// catch (Exception e)
		// {
		// e.printStackTrace();
		// log.severe(e.getLocalizedMessage());
		//
		// // throw new BackendException(EErrorCodes.SERVER_ERROR,
		// // e.getLocalizedMessage());
		// throw new BackendException(EErrorCodes.SERVER_ERROR);
		// }
	}

}
